package com.hqyj.service;

import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import com.hqyj.dao.ManagerInfoDao;
import com.hqyj.dao.ResultInfoDao;
import com.hqyj.dao.UserInfoDao;
import com.hqyj.dao.UserSerInfoDao;
import com.hqyj.pojo.ManagerInfo;
import com.hqyj.pojo.Resultinfo;
import com.hqyj.pojo.UserInfo;
import com.hqyj.pojo.UserSerInfo;
import com.hqyj.util.MdFive;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.mail.SimpleMailMessage;
import org.springframework.mail.javamail.JavaMailSender;
import org.springframework.stereotype.Service;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpSession;
import java.io.Console;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Random;
import java.util.concurrent.TimeUnit;

@Service//userinfoservice创建的对象交给springguanli1
public class UserInfoServiceImpl implements UserInfoService{
    //创建一个userinfodao的实现类对线
    @Autowired
   RedisTemplate<String, Object> redisTemplate;

    @Autowired(required = false)
    UserInfoDao userInfoDao;

    @Autowired(required = false)
    ManagerInfoDao managerInfoDao;


    //创建一个UserSerInfoDao的实现类对象
    @Autowired(required = false)
    UserSerInfoDao userSerInfoDao;
    //创建一个ResultInfoDao的实现类对象
    @Autowired(required = false)
    ResultInfoDao resultInfoDao;

    //创建加密工具对象
    @Autowired
    MdFive mdFive;
    //获取发件人邮箱
    @Value("${spring.mail.username}")
    String sendEmail;
    //创建发送邮件的对象
    @Autowired
    JavaMailSender javaMailSender;
    /**
     * 检查用户是否已经被锁定，如果是，返回剩余锁定时间，如果否，返回-1
     * @param username  username
     * @return  时间
     */
    private long getUserLoginTimeLock(String username) {
        String key = "user:" + username + ":lockTime";
        //获取key 过期时间
        long lockTime = redisTemplate.getExpire(key, TimeUnit.SECONDS);

        if(lockTime > 0){//查询用户是否已经被锁定，如果是，返回剩余锁定时间，如果否，返回-1
            return lockTime;
        }else{
            return -1;
        }
    }

    private int getUserFailCount(String username){
        String key = "user:" + username + ":failCount";
        //从redis中获取当前用户已失败次数
        Object object = redisTemplate.opsForValue().get(key);
        if(object != null){
            return (int)object;
        }else{
            return -1;
        }
    }
    /**
     * 设置失败次数
     * @param username  username
     */
    private void setFailCount(String username){
        //获取当前用户已失败次数
        long count = this.getUserFailCount(username);
        String key = "user:" + username + ":failCount";
        if(count < 0){//判断redis中是否有该用户的失败登陆次数，如果没有，设置为1，过期时间为1分钟，如果有，则次数+1
            redisTemplate.opsForValue().set(key,1,60,TimeUnit.SECONDS);
        }else{
            redisTemplate.opsForValue().increment(key,new Double(1));
        }
    }

    @Override
    public String login(UserInfo user,ManagerInfo mag, HttpServletRequest request) {
        System.out.print(user.getLoginna()+"*************************************************************");
        if (user.getLoginna().equals("经理"))
        {
            ManagerInfo m = managerInfoDao.seByManName(user);
            if (m!=null){
                //加密用户输入的密码
                String pwd = mdFive.encrypt(user.getUserPwd(), m.getSalt());
                //把加过密的密码传到数据层中
                user.setUserPwd(pwd);
                //查询数据层的登录方法，并且拿到返回值
                ManagerInfo managerInfo= managerInfoDao.login(user);
                //如果查询到值，userinfo就不为null,否则就等于null
                if(managerInfo!=null)
                {
                    //创建session对象
                    HttpSession session=request.getSession();
                    //存入用户对象
                    session.setAttribute("mag",managerInfo);
                    if (user.getUserName().equals("admin"))
                    return "登录成功管理员";
                    else
                        return "登录成功经理";
                }else {return "密码错误";}
            }
            else {return "账号不存在";}

        }
        else {
            if (this.getUserLoginTimeLock(user.getUserName()) < 0) {
                UserInfo u = userInfoDao.selectByName(user);
                if (u != null) {
                    //加密用户输入的密码
                    String pwd = mdFive.encrypt(user.getUserPwd(), u.getSalt());
                    //把加过密的密码传到数据层中
                    user.setUserPwd(pwd);
                    user.setSpwd(pwd);
                    user.setManagerPwd(pwd);
                    //查询数据层的登录方法，并且拿带到返回值
                    UserInfo userInfo = userInfoDao.login(user);
                    //如果查询到值，userinfo就不等于ull
                    if (userInfo != null) {
                        //创建session对象
                        HttpSession session = request.getSession();
                        //存入用户对象
                        session.setAttribute("user", userInfo);
                        System.out.print(user.getUserName());
                        System.out.print(user.getUserPhoto()+"*************************************************");
                        return "登录成功";
                    } else {

                        //设置密码输入失败次数
                        setFailCount(user.getUserName());
                        //获取密码失败次数
                        int num = getUserFailCount(user.getUserName());
                        //定义用户允许失败的次数
                        int cc = 3;
                        //剩余失败次数
                        int d = cc - num;
                        if (d > 0) {
                            return "你输入密码错误" + num + "次，还剩余" + d + "次";
                        } else {
                            String key = "user:" + user.getUserName() + ":failCount";
                            redisTemplate.opsForValue().set(key, 222, 60, TimeUnit.SECONDS);
                            return "你输入密码次数超过" + cc + ",用户已经被锁定";
                        }
                    }
                }
                else {

                    UserInfo userInfo1 = userInfoDao.loginT(user);
                    if (userInfo1 != null) {
                        userInfo1.setUserName(userInfo1.getManagerName());
                        userInfo1.setUserPwd(userInfo1.getManagerPwd());

                        HttpSession session = request.getSession();
                        //存入用户对象
                        session.setAttribute("user", userInfo1);
                        return "密码错误";//密码输入错误
                    } else {
                        return "用户名输入错误";
                    }
                }

            } else {
                return "用户账号已解决锁定，请一分钟后再试";
            }
        }
        //查询用户名是否存在，如果存在就取出它的盐值

    }

    @Override
    public String zhuce(UserInfo user) {
        //判断用户是否锁定

        //查询用户名是否重名
        int num=userInfoDao.valName(user);
        int num1=userInfoDao.valEmail(user);
        int num2=userInfoDao.valTel(user);
        int num4=userInfoDao.valmanager(user);
        if(num>0){
            return "用户名已经被注册";
        }else{

            if(num1>0){
                return "邮箱已经被注册或为空";
            }else{
                if(num2>0){
                    return "手机号已经被注册";
                }else {
                    if (num4 > 0) {
                        if(user.getName().equals("")){
                            return "姓名不能为空";
                        }else{
                            if(user.getUserEdu().equals("")){
                                return "学历不能为空";
                            }else{
                                if (user.getUserUnit().equals("")){
                                    return "工作单位不能为空";
                                }else {
                                    if (user.getUserPhoto().equals("")){
                                        return "头像为空";
                                    }else {
                                        Random rd = new Random();
                                        String salt = rd.nextInt(10000) + "";
                                        //注册
                                        String pwd = mdFive.encrypt(user.getUserPwd(), salt);
                                        //把加过密的密码传到数据层中
                                        user.setUserPwd(pwd);
                                        System.out.println(user.getUserName()+user.getUserEdu()+user.getUserUnit()+"-------------------");
                                        //存入盐值
                                        user.setSalt(salt);
                                        int n = userInfoDao.zhuce(user);
                                        if (n > 0) {
                                            return "注册成功";
                                        }
                                    }


                                }

                            }

                        }


                    } else {
                        return "用户经理不存在或为空";
                    }
                }
                }

        }
        return "注册失败";
    }
    @Override
    public HashMap<String, Object> sendCode(String email, HttpServletRequest request) {
        HashMap<String, Object> map = new HashMap<String, Object>();
        try {
            //从session中获取当前用户信息
            HttpSession session = request.getSession();
            //创建普通邮件对象
            SimpleMailMessage message = new SimpleMailMessage();
            //设置发件人邮箱
            message.setFrom(sendEmail);
            //设置收件人邮箱
            message.setTo(email);
            //设置邮件主题
            message.setSubject("学员信息管理系统验证码");
            // 生成随机验证码
            Random rd = new Random();
            String valCode = rd.nextInt(9999)+"";
            //设置邮件正文
            message.setText(valCode);
            //发送邮件
            javaMailSender.send(message);
            //发送成功
            //把验证码存入session中
            session.setAttribute("valCode",valCode);
            //把验证码存入到redis中
          //  redisTemplate.opsForValue().set("valCode",valCode,180,);
            map.put("info","发送成功");
            return map;

        } catch (Exception e) {
            System.out.println("发送邮件时发生异常！");
            e.printStackTrace();
        }
        map.put("info","发送邮件异常");
        return map;
    }

    @Override
    public HashMap<String, Object> select(UserInfo user) {
        HashMap<String, Object> map =new HashMap<>();
        //根据用户的查询条件判断用户需要的查询

        //1 设置分页查询的页码，每页显示的行数
        PageHelper.startPage(user.getPage(),user.getRow());
        List<UserInfo> list =new ArrayList<>();
        //判断用户输入的查询条件是否有值
        if(user.getConValue().equals("")){

            //判断redis中是否有数据
            list = userInfoDao.select();
           /* String key = "wen";
           Object obj= redisTemplate.opsForValue().get(key);
           if(obj==null){
               //查询sql数据库
               list = userInfoDao.select();
               System.out.println(":::::::::::::::::::::::::::::::"+list);
               //存入缓存
               redisTemplate.opsForValue().set(key,list,10,TimeUnit.MINUTES);
           }else {
               list = (List<UserInfo>) obj;
           }*/
        } else {


            if (user.getCondition().equals("编号")) {
                //设置用户输入的查询条件
                user.setUserId(Integer.parseInt(user.getConValue()));

                list = userInfoDao.findByUserId(user);
            } else if (user.getCondition().equals("用户名")) {

                user.setUserName(user.getConValue());
                list = userInfoDao.findByUserName(user);
            } else {
                list = userInfoDao.select();
                System.out.println();
            }
        }
        //3 创建分页对象,查训的数据转换成对象
        PageInfo<UserInfo> page = new PageInfo<UserInfo>(list);
        //获取分页的当前页的集合
        map.put("list",page.getList());
        //总条数
        map.put("total",page.getTotal());
        System.out.println("total:::::::::::::::::::::::::::::::"+list);
        System.out.println("total:::::::::::::::::::::::::::::::"+page.getTotal());
        System.out.println("total:::::::::::::::::::::::::::::::"+page.getList());
        //总页数
        map.put("totalPage",page.getPages());
        //上一页
        if(page.getPrePage()==0){
            map.put("pre",1);
        }else {
            map.put("pre", page.getPrePage());
        }
        //下一页,判断下一页的值是否大于等于最后一页
        if(page.getNextPage()==0){
            map.put("next", page.getPages());

        }else {
            map.put("next", page.getNextPage());
        }
        //当前页
        map.put("cur",page.getPageNum());
        return map;
    }

    @Override
    public UserInfo selectByUserId(UserInfo user) {
        return userInfoDao.selectByUserId(user);
    }

    @Override
    public String update(UserInfo user) {

        //
        int v =userInfoDao.valName(user);
        if(v==0){
            int num = userInfoDao.update(user);
            if(num>0){
                //更新缓存
               //String key = "wen";
             //  List<UserInfo> list =userInfoDao.select();
              //  list = userInfoDao.select();
                //存入缓存
               // redisTemplate.opsForValue().set(key,list,10,TimeUnit.MINUTES);
                return "修改成功";

            }
        }else{
            return "用户重名";
        }
        return "修改失败";
    }

    @Override
    public String del(UserInfo user) {
        int num = userInfoDao.del(user);
        if(num>0){
            return "删除成功";
        }
        return "删除失败";
    }

    @Override
    public String add(UserInfo user) {
        int num=userInfoDao.valName(user);
        if(num>0){
            return "用户名已经被注册";
        }else{
            //自动生成一个盐值
            Random rd = new Random();
            String salt = rd.nextInt(10000)+"";
            //注册
            String pwd = mdFive.encrypt(user.getUserPwd(),salt);
            //把加过密的密码传到数据层中
            user.setUserPwd(pwd);
            //存入盐值
            user.setSalt(salt);
            int n =  userInfoDao.add(user);
            if(n>0){
                return "注册成功";
            }
        }
        return "注册失败";
    }

    @Override
    public String updatePwd(UserInfo user, HttpServletRequest request) {

        //取出用户存入session中的密码
        //创建session
        HttpSession session = request.getSession();
        UserInfo u = (UserInfo) session.getAttribute("user");
        String pwd =u.getUserPwd();
        //加密下旧密码
        String oldPwd = mdFive.encrypt(user.getOldPwd(),u.getSalt());
        //判断用户输入的旧密码是否正确
        if(oldPwd.equals(pwd)){
            //查询用户的盐值
            UserInfo uu = userInfoDao.selectByName(u);
            //加密
            String p = mdFive.encrypt(user.getNewPwd(),uu.getSalt());
            //存入加密后的密码
            u.setUserPwd(p);
            int num = userInfoDao.updatePwd(u);
            if(num>0){
                return "修改密码成功";
            }
        }else{
            return "旧密码输入不正确";
        }
        return "密码修改失败";
    }

    @Override
    public String updateHead(UserInfo user, HttpServletRequest request) {
        //获取session
        HttpSession session = request.getSession();
        UserInfo u = (UserInfo) session.getAttribute("user");
        //存入要修改的用户id
        user.setUserId(u.getUserId());
        System.out.print(user.getUserPhoto());
        System.out.print(user.getUserId()+"_________________________________________");
        //
        int num = userInfoDao.updateHead(user);
        if(num>0){
            return "保存成功";
        }
        return "保存失败";

    }
    //查询当前用户信息
    @Override
    public UserInfo selectu(UserInfo user) {
        return userInfoDao.selectuser(user);
    }

    //修改用户信息
    @Override
    public String userUpdate(UserInfo user) {
        //判断用户是否重名
        int v=userInfoDao.seluserName(user);
        //判断管理员是否存在
        int m= managerInfoDao.seluserManger(user);
        System.out.println(m);
        if (v==0) {
            if (m>0) {
                int num = userInfoDao.updateUserInfo(user);
                System.out.println(num);
                if (num > 0) {
                    return "保存成功";
                }
            }
            else {return "经理不存在";}
        }else {return "用户重名";}
        return "保存失败";
    }

    //注销用户信息
    @Override
    public String delUser(UserInfo user) {
        int num = userInfoDao.deluse(user);
        System.out.println(num);
        if(num>0){
            return "注销成功";
        }
        return "注销失败";
    }

    //分页查询用户的申请服务请求
    @Override
    public HashMap<String, Object> selectuserser(UserInfo user, UserSerInfo ser) {
        HashMap<String, Object> map=new HashMap<String, Object>();
        //1设置分页参数
        PageHelper.startPage(ser.getPage(),ser.getRow());
        //2查询数据库表数据
        List< UserSerInfo> list=new ArrayList<>();

        //判断用户输入的查询条件是否有值
        if(ser.getConValue().equals("")) {
            //空值查询所有
            list=userSerInfoDao.selectuserser(ser);
        }else {
            //根据用户选择的查询条件，判断用户需要查询的
            if (ser.getCondition().equals("编号")) {
                //设置用户输入的查询条件
                ser.setSerId(Integer.parseInt(ser.getConValue()));
                list = userSerInfoDao.findBySerId(ser);
            }  else if (ser.getCondition().equals("服务类型"))
            {
                //服务类型的查询
                ser.setSerType(ser.getConValue());
                list = userSerInfoDao.findByserType(ser);
            }else if (ser.getCondition().equals("服务日期")){
                //服务时间的查询
                ser.setSerTime(ser.getConValue());
                list = userSerInfoDao.findByserTime(ser);
            }else if (ser.getCondition().equals("经理是否已读"))
            {
                //服务经理是否已读查询
                ser.setSerRead(ser.getConValue());
                list = userSerInfoDao.findByserRead(ser);

            }else {
                //空值查询所有
                list = userSerInfoDao.selectuserser(ser);
            }
        }

        //分页操作
        //3.把查询出来的数据转换成分页对象
        PageInfo<UserSerInfo> page = new PageInfo<UserSerInfo>(list);

        //获取分页的当前页的集合
        map.put("list",page.getList());
        //总条数
        map.put("total",page.getTotal());
        //总页数
        map.put("totalPage",page.getPages());
        //上一页
        if (page.getPrePage()==0){
            map.put("pre",1);
        }else
        {
            map.put("pre",page.getPrePage());
        }
        //下一页,判断下一页的值是否大于等于最后一页
        if (page.getNextPage()==0)
        {
            map.put("next",page.getPages());
        }else {
            map.put("next", page.getNextPage());
        }
        //当前页
        map.put("cur",page.getPageNum());

        return map;
    }

    //通过id查询用户服务
    @Override
    public UserSerInfo selectByserId(UserSerInfo ser) {
        return userSerInfoDao.selectByserId(ser);
    }

    //保存用户的修改的服务
    @Override
    public String upService(UserSerInfo ser) {
        int num = userSerInfoDao.upService(ser);
        if(num>0){
            return "保存成功";
        }
        return "保存失败";
    }

    //删除用户的服务
    @Override
    public String delservice(UserSerInfo ser) {
        int num = userSerInfoDao.delservice(ser);
        System.out.println(num);
        if(num>0){
            return "删除成功";
        }
        return "删除失败";
    }

    //新增服务查询用户的部分信息
    @Override
    public UserInfo selectUserSer(UserSerInfo ser) {
        return userInfoDao.selectUserSer(ser);
    }

    //处理保存新增服务操作
    @Override
    public String serveadd(UserSerInfo ser) {
        //插入数据
        int num = userSerInfoDao.serveadd(ser);
        System.out.println(num);
        if (num > 0) {
            return "保存成功";
        }
        return "保存失败";
    }

    //分页查询服务返回结果
    @Override
    public HashMap<String, Object> selectresult(Resultinfo resu) {
        HashMap<String, Object> map=new HashMap<String, Object>();
        //1设置分页参数
        PageHelper.startPage(resu.getPage(),resu.getRow());
        //2查询数据库表数据
        List< Resultinfo> list=new ArrayList<>();

        //判断用户输入的查询条件是否有值
        if(resu.getConValue().equals("")) {
            //空值查询所有
            list=resultInfoDao.selectuserser(resu);
        }else {
            //根据用户选择的查询条件，判断用户需要查询的
            if (resu.getCondition().equals("编号")) {
                //设置用户输入的查询条件
                resu.setResultId(Integer.parseInt(resu.getConValue()));
                list = resultInfoDao.findBySerId(resu);
            }  else if (resu.getCondition().equals("服务类型"))
            {
                //服务类型的查询
                resu.setSerType(resu.getConValue());
                list = resultInfoDao.findByserType(resu);
            }else if (resu.getCondition().equals("服务日期")){
                //服务时间的查询
                resu.setSerTime(resu.getConValue());
                list = resultInfoDao.findByserTime(resu);
            }else if (resu.getCondition().equals("处理人"))
            {
                //处理人查询
                resu.setResultManager(resu.getConValue());
                list = resultInfoDao.findByPeople(resu);
            }else if (resu.getCondition().equals("完成时间"))
            {
                //完成时间查询
                resu.setResultTimei(resu.getConValue());
                list = resultInfoDao.findByoverTime(resu);
            }else {
                //空值查询所有
                list=resultInfoDao.selectuserser(resu);

            }
        }

        //分页操作
        //3.把查询出来的数据转换成分页对象
        PageInfo<Resultinfo> page = new PageInfo<Resultinfo>(list);

        //获取分页的当前页的集合
        map.put("list",page.getList());
        //总条数
        map.put("total",page.getTotal());
        //总页数
        map.put("totalPage",page.getPages());
        //上一页
        if (page.getPrePage()==0){
            map.put("pre",1);
        }else
        {
            map.put("pre",page.getPrePage());
        }
        //下一页,判断下一页的值是否大于等于最后一页
        if (page.getNextPage()==0)
        {
            map.put("next",page.getPages());
        }else {
            map.put("next", page.getNextPage());
        }
        //当前页
        map.put("cur",page.getPageNum());

        return map;
    }

    //根据服务结果查询返回的id查询服务selectByresultId
    @Override
    public Resultinfo selectByresultId(Resultinfo result) {
        return resultInfoDao.selectByresultId(result);
    }

    @Override
    public String uprequist(Resultinfo result) {
        //向申请服务表中修改当前修改的数据
        int num = userSerInfoDao.upService(result);
        //向服务结果表中修改当前服务
        int re = resultInfoDao.uprequist(result);
        if(num>0 && re>0){
            return "保存成功";
        }
        return "保存失败";
    }
}

